對程式來說,檔案的處理與網絡傳輸是差不多的,所以會有一些兩者都通用的函式
最主要就是這兩個函式:
這兩個函式是其他一堆函式經過包裝後的,所以用起來非常的輕鬆容易
$file = 'data.txt';
// 讀取檔案
$current = file_get_contents($file);
// 修改內容
$current .= "增加一些內容\n";
// 寫入檔案
file_put_contents($file, $current, LOCK_EX);
// LOCK_EX 可以避免寫入時被存取
$file = 'data.txt';
$current = "增加一些內容";
// 寫入檔案
file_put_contents($file, $current, FILE_APPEND | LOCK_EX);
// FILE_APPEND 可以寫入新的一行
但是會遇到一個很常見的問題,而且這兩個函式無法處理
競爭危害 Race Condition:
這樣就造成了檔案裡只剩下 B 增加的內容,所以接下來要介紹其他的內建函式
其他內建函式:
函式 | 說明 | 用法 |
---|---|---|
mkdir() |
新增目錄(資料夾) | mkdir($path) |
unlink() |
刪除檔案 | unlink($path) |
rmdir() |
刪除目錄(資料夾) | rmdir($path) |
rename() |
重新命名檔案或目錄 | rename($old_path, $new_path) |
file_exists() |
檢查檔案或目錄是否存在 | file_exists($path) |
is_dir() |
檢查是否為目錄 | is_dir($path) |
is_file() |
檢查是否為檔案 | is_file($path) |
filesize() |
檔案的大小 | filesize($path) |
fopen() |
開啟檔案 | fopen($path, $mode) |
flock() |
鎖定檔案 | flock($fp, $option) |
ftruncate() |
截斷檔案(刪除大於設定的內容) | ftruncate($fp, $size) |
rewind() |
將檔案的指標位置移至檔頭 | rewind($fp) |
ftell() |
返回指標位置 | ftell($fp) |
fseek() |
移動指標位置 | fseek($fp, $pos); |
fgets() |
從指標位置讀取一行 | fgets($fp); |
fread() |
從指標位置讀取指定長度 | fread($fp, $length); |
fwrite() |
從指標位置寫入 | fwrite($fp, $string); |
fclose() |
關閉檔案 | fclose($fp); |
檔案指標(File Pointer)其實就跟你打字時會閃爍的游標很像,在開啟檔案時它會在開頭的位置,讀取和寫入後,都會移動到讀取/寫入文字的後方
要解決剛剛那個問題很簡單,只要在讀取時就把檔案鎖住(LOCK_EX),寫入完畢時釋放(LOCK_UN)就行了
// 開啟檔案
$fp = fopen('data.txt', 'r+');
// 上鎖
if (flock($fp, LOCK_EX)) {
// 讀取整份檔案,並存進 data 變數
$data = fread($fp, filesize('data.txt'));
// 修改 data 內容
$data .= "增加一些內容\n";
// 刪除檔案內容
ftruncate($fp, 0);
// 將指標歸零
rewind($fp);
// 寫入檔案
fwrite($fp, $data);
// 解鎖
flock($fp, LOCK_UN);
// 關閉檔案
fclose($fp);
}
這樣的話就沒有人可以在你讀寫時存取檔案,必須等到你解鎖他才能讀取
fopen 模式:
符號 | 模式 | 說明 |
---|---|---|
r |
讀取 | 不存在會出錯,指標在開頭 |
r+ |
讀取、寫入 | 同r |
w |
寫入 | 不存在會建立檔案,指標在開頭,清空檔案 |
w+ |
讀取、寫入 | 同w |
a |
寫入 | 不存在會建立檔案,指標在結尾。fseek() 無效,寫入總是在結尾。 |
a+ |
讀取、寫入 | 同a |
x |
寫入 | 已存在會出錯,指標在開頭 |
x+ |
讀取、寫入 | 同x |
c |
寫入 | 不存在會建立檔案,指標在開頭,不清空檔案 |
c+ |
讀取、寫入 | 同c |
flock 選項:
選項 | 說明 |
---|---|
LOCK_SH |
可以讀取,不能寫入(其他人) |
LOCK_EX |
不能讀取和寫入(其他人) |
LOCK_UN |
釋放 LOCK |
LOCK_NB |
嘗試非阻塞 |
所有檔案處理函式:https://www.php.net/manual/en/ref.filesystem.php
cURL 是一個用於網路傳輸的開源工具(函式庫),在 Windows 10 的小黑框中也能使用
函式 | 說明 | 用法 |
---|---|---|
curl_init() |
初始化連線 | curl_init($url) |
curl_setopt() |
設定傳輸選項 | curl_setopt($ch, $option, $value) |
curl_setopt_array() |
以陣列方式設定傳輸選項 | curl_array($ch, $options) |
curl_exec() |
執行傳輸 | curl_exec($ch) |
curl_getinfo() |
讀取回應資訊 | curl_getinfo($ch, $option) |
curl_close() |
關閉連線 | curl_close($ch) |
所有 cURL 函式:https://www.php.net/manual/en/ref.curl.php
其實主要就這四個步驟:
很容易對吧~
curl_setopt 選項:
選項 | 說明 |
---|---|
CURLOPT_RETURNTRANSFER |
返回字串而不是直接輸出 |
CURLOPT_CONNECTTIMEOUT |
嘗試連線的最大秒數 |
CURLOPT_TIMEOUT |
設定函式執行的最長秒數 |
CURLOPT_POST |
發送 POST 請求 |
CURLOPT_POSTFIELDS |
設定傳送的檔案 |
CURLOPT_HTTPHEADER |
設定 HTTP 檔頭(Header) |
所有 cURL 選項:https://www.php.net/manual/en/function.curl-setopt.php
// HTTP GET
$handle = curl_init("https://httpbin.org/get?a=air&b=bag&c=cat");
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($handle, CURLOPT_TIMEOUT, 60);
$response = curl_exec($handle);
curl_close($handle);
echo $response;
// HTTP POST
$handle = curl_init("https://httpbin.org/post");
curl_setopt_array($handle, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 60,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
'a' => 'air',
'b' => 'bag',
'c' => 'cat'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
]
]);
$response = curl_exec($handle);
curl_close($handle);
echo $response;